﻿using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;


namespace XFGameFramework.Localization
{
    [CustomEditor(typeof(LocalizeString))]
    public class LocalizeStringInspector : Editor
    {

        private List<SerializedProperty> properties = null;

        private SerializedProperty m_Script = null;
        private SerializedProperty componentType = null;

        private SerializedProperty id = null;


        private LocalizeString localizeString = null;

        private GUIContent idContent = null;

        private ReorderableList appendsList = null;

        private GUIContent richTextContent = null;
        private GUIStyle richTextStyle = null;

        private static Dictionary<int, GUIContent> typeContents = new Dictionary<int, GUIContent>();

        private static Dictionary<int, GUIContent> idContents = new Dictionary<int, GUIContent>();

        private GUIStyle previewStyle = null;

        private ReorderableList argsList = null;

        private int idValue = 0;

        private void OnEnable()
        {
            localizeString = target as LocalizeString;
            properties = serializedObject.GetAllSerializedProperty();
            m_Script = serializedObject.FindProperty("m_Script");
            componentType = serializedObject.FindProperty("componentType");

            id = serializedObject.FindProperty("id");

            idValue = id.intValue;
        }


        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUI.BeginDisabledGroup(true);

            EditorGUILayout.PropertyField(m_Script);

            EditorGUI.EndDisabledGroup();
             
            OnIDGUI(id);

           

            foreach (var item in properties)
            {
                if (item.name == "id") continue;

                if (item.name == "componentFullName" || item.name == "fieldName")
                {
                    if (componentType.enumValueIndex != (int)ComponentType.Other)
                    {
                        continue;
                    }
                }

                if (item.name == "componentFullName" || item.name == "fieldName")
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Space(10);
                    EditorGUILayout.PropertyField(item);
                    GUILayout.EndHorizontal();
                }
                else if (item.name == "appends")
                {
                    OnAppendsGUI(item);
                }
                else if (item.name == "args") {
                    OnArgsGUI(item);
                }
                else
                {
                    EditorGUILayout.PropertyField(item);
                }

            }

            
            serializedObject.ApplyModifiedProperties();

            Preview();

        }


        private void OnIDGUI(SerializedProperty id)
        {


            EditorGUILayout.LabelField(string.Empty, "语言配置ID", "BoldLabel");
            GUILayout.BeginHorizontal();

            GUILayout.Label("ID");

            if (idContent == null)
                idContent = new GUIContent();

            LanguageInfo info = LocalizationManager.GetLanguageInfo(id.intValue);

            idContent.text = string.Format("{0}({1})",id.intValue,info == null ? "未查询到配置": info.str);

            if (EditorGUILayout.DropdownButton(idContent, FocusType.Passive)) 
            { 
                LanguageSearchWindow window = EditorWindow.GetWindow<LanguageSearchWindow>();
                window.Init(id, MultiLanguageType.String);
            }

            GUILayout.EndHorizontal();

            if (idValue != id.intValue)
            {
                MethodInfo method = typeof(LocalizeString).GetMethod("SetValue", BindingFlags.NonPublic | BindingFlags.Instance);
                method.Invoke(target, null); 

                EditorUtility.SetDirty(target);

                idValue = id.intValue;
            }

        }

        #region 参数

        private void OnArgsGUI(SerializedProperty appends)
        {

            if (argsList == null)
            {
                argsList = new ReorderableList(serializedObject, appends);
                argsList.drawHeaderCallback += HeaderCallbackDelegateArgs;
                argsList.drawElementCallback += ElementCallbackDelegateArgs;
            }

            GUILayout.Space(10);
            GUILayout.Label("参数", "BoldLabel");
            argsList.DoLayoutList();
        }

        private void HeaderCallbackDelegateArgs(Rect rect)
        {
            EditorGUI.BeginDisabledGroup(true);

            rect.width /= 4;
            rect.x += 15;
            GUI.Label(rect, "类型", "BoldLabel");

            rect.x += rect.width - 5;
            rect.width *= 2;
            GUI.Label(rect, "值", "BoldLabel");

            if (richTextContent == null)
            {
                richTextContent = new GUIContent();
                richTextContent.text = "富文本(格式:<color=red>{0}</color>)";
                richTextContent.tooltip = "格式:<标签>{0}</标签>";
            }

            if (richTextStyle == null)
            {
                richTextStyle = new GUIStyle("BoldLabel");
                richTextStyle.richText = false;
            }


            rect.x += rect.width - 10;
            rect.width /= 2;

            GUI.Label(rect, richTextContent, richTextStyle);

            EditorGUI.EndDisabledGroup();
        }

        private void ElementCallbackDelegateArgs(Rect rect, int index, bool isActive, bool isFocused)
        {
            if (index < 0 || index >= argsList.serializedProperty.arraySize)
                return;
            rect.width /= 4;

            SerializedProperty property = argsList.serializedProperty.GetArrayElementAtIndex(index);

            SerializedProperty type = property.FindPropertyRelative("type");
            SerializedProperty id = property.FindPropertyRelative("id");
            SerializedProperty str = property.FindPropertyRelative("str");
            SerializedProperty richText = property.FindPropertyRelative("richText");

            if (!typeContents.ContainsKey(index))
                typeContents.Add(index, new GUIContent());

            typeContents[index].text = type.enumDisplayNames[type.enumValueIndex];

            if (EditorGUI.DropdownButton(rect, typeContents[index], FocusType.Passive))
            {
                GenericMenu menu = new GenericMenu();

                for (int i = 0; i < type.enumDisplayNames.Length; i++)
                {
                    if (i == type.enumValueIndex)
                    {
                        menu.AddDisabledItem(new GUIContent(type.enumDisplayNames[i]), true);
                    }
                    else
                    {
                        int enumValueIndex = i;
                        menu.AddItem(new GUIContent(type.enumDisplayNames[i]), false, () =>
                        {
                            type.enumValueIndex = enumValueIndex;
                            type.serializedObject.ApplyModifiedProperties();
                        });
                    }
                }

                menu.ShowAsContext();
            }

            rect.x += rect.width;
            rect.width *= 2;
            switch (type.enumValueIndex)
            {
                case 0:

                    if (!idContents.ContainsKey(index))
                        idContents.Add(index, new GUIContent());
                    LanguageInfo info = LocalizationManager.GetLanguageInfo(id.intValue);
                    idContents[index].text = string.Format("{0}({1})", id.intValue, info == null ? "未查询到配置" : info.str);

                    if (EditorGUI.DropdownButton(rect, idContents[index], FocusType.Passive))
                    {
                        LanguageSearchWindow window = EditorWindow.GetWindow<LanguageSearchWindow>();
                        window.Init(id, MultiLanguageType.String);
                    }

                    break;
                case 1:
                    str.stringValue = EditorGUI.TextField(rect, str.stringValue);
                    break;
            }

            rect.x += rect.width;
            rect.width /= 2;
            richText.stringValue = EditorGUI.TextField(rect, richText.stringValue);
        }


        #endregion

        #region 附加数据


        private void OnAppendsGUI(SerializedProperty appends) 
        {

            if (appendsList == null) 
            {
                appendsList = new ReorderableList(serializedObject, appends);
                appendsList.drawHeaderCallback += HeaderCallbackDelegate;
                appendsList.drawElementCallback += ElementCallbackDelegate;
            }

            GUILayout.Space(10);
            GUILayout.Label("附加数据", "BoldLabel");
            appendsList.DoLayoutList(); 
        }

        private void HeaderCallbackDelegate(Rect rect) 
        {
            EditorGUI.BeginDisabledGroup(true);

            rect.width /= 4;
            rect.x += 15;
            GUI.Label(rect,"类型", "BoldLabel");

            rect.x += rect.width - 5;
            rect.width *= 2;
            GUI.Label(rect, "值", "BoldLabel");

            if (richTextContent == null)
            {
                richTextContent = new GUIContent();
                richTextContent.text = "富文本(格式:<color=red>{0}</color>)";
                richTextContent.tooltip = "格式:<标签>{0}</标签>"; 
            }

            if (richTextStyle == null) 
            {
                richTextStyle = new GUIStyle("BoldLabel");
                richTextStyle.richText = false;
            }


            rect.x += rect.width - 10;
            rect.width /= 2;
             
            GUI.Label(rect, richTextContent, richTextStyle);
              
            EditorGUI.EndDisabledGroup();
        }

        private void ElementCallbackDelegate(Rect rect, int index, bool isActive, bool isFocused) 
        {
            if (index < 0 || index >= appendsList.serializedProperty.arraySize)
                return;
            rect.width /= 4;

            SerializedProperty property = appendsList.serializedProperty.GetArrayElementAtIndex(index);

            SerializedProperty type = property.FindPropertyRelative("type");
            SerializedProperty id = property.FindPropertyRelative("id");
            SerializedProperty str = property.FindPropertyRelative("str");
            SerializedProperty richText = property.FindPropertyRelative("richText");

            if (!typeContents.ContainsKey(index))
                typeContents.Add(index, new GUIContent());

            typeContents[index].text = type.enumDisplayNames[type.enumValueIndex];

            if (EditorGUI.DropdownButton(rect,typeContents[index], FocusType.Passive)) 
            {
                GenericMenu menu = new GenericMenu();
                 
                for (int i = 0; i < type.enumDisplayNames.Length; i++)
                {
                    if (i == type.enumValueIndex)
                    {
                        menu.AddDisabledItem(new GUIContent(type.enumDisplayNames[i]), true);
                    }
                    else 
                    {
                        int enumValueIndex = i;
                        menu.AddItem(new GUIContent(type.enumDisplayNames[i]), false, () => 
                        {
                            type.enumValueIndex = enumValueIndex;
                            type.serializedObject.ApplyModifiedProperties();
                        });
                    }
                }
                
                menu.ShowAsContext();
            }

            rect.x += rect.width;
            rect.width *= 2;
            switch (type.enumValueIndex)
            {
                case 0: 

                    if(!idContents.ContainsKey(index))
                        idContents.Add(index, new GUIContent());
                    LanguageInfo info = LocalizationManager.GetLanguageInfo(id.intValue);
                    idContents[index].text = string.Format("{0}({1})", id.intValue, info == null ? "未查询到配置" : info.str);

                    if (EditorGUI.DropdownButton(rect, idContents[index], FocusType.Passive))
                    {
                        LanguageSearchWindow window = EditorWindow.GetWindow<LanguageSearchWindow>();
                        window.Init(id, MultiLanguageType.String);
                    }

                    break;
                case 1:
                    str.stringValue = EditorGUI.TextField(rect, str.stringValue);
                    break;
            }

            rect.x += rect.width;
            rect.width /= 2; 
            richText.stringValue = EditorGUI.TextField(rect, richText.stringValue);
        }


        #endregion

        private void Preview() 
        {
            if(previewStyle == null)
                previewStyle = new GUIStyle("BoldLabel");

            previewStyle.richText = true;

            EditorGUI.BeginDisabledGroup(true);
            GUILayout.Space(10);
            EditorGUILayout.LabelField(string.Empty, "预览", "BoldLabel");
            EditorGUILayout.LabelField(string.Empty, localizeString.GetString(), previewStyle);
            EditorGUI.EndDisabledGroup();
        }

    }

}

